package library.base;

import android.app.Activity;
import android.content.Context;
import android.content.res.Configuration;
import android.os.Bundle;
import android.support.multidex.MultiDex;
import android.support.multidex.MultiDexApplication;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import library.base.mvp.v.activity.BaseActivity;
import library.base.mvp.v.activity.BaseAppCompatActivity;
import library.base.mvp.v.activity.BaseFragmentActivity;
import library.common.util.SharedUtils;
import library.router.ModuleRouter;

/**
 * @author Created by qiang.hou on 2018/3/14.
 * @version 1.0
 */
public abstract class BaseApplication
        extends MultiDexApplication implements IApplication {

    /**
     * app有效activity缓存
     */
    private List<WeakReference<Activity>> activityList = new ArrayList();
    /**
     * app当前activity缓存
     */
    private List<WeakReference<Activity>> currentActivityList = new ArrayList();

    private static BaseApplication INSTANCE;

    public static BaseApplication getInstance() {
        return INSTANCE;
    }

    public static Context getContext() {
        return INSTANCE == null ? null : INSTANCE.getBaseContext();
    }

    @Override
    public void onCreate() {
        super.onCreate();
        INSTANCE = this;
        registerActivityLifecycleCallbacks(this);
        /*
         * 组件化框架使用，非组件化无用
         */
        initModules();
        /*
         * 组件化框架使用，非组件化无用
         */
        initRouter();
        initNetworkConfig();
        initSharedPreference(defineSharedPreferenceName());
        initOtherConfig();
        /*
         * 组件化框架调用组件生命周期，非组件化无用
         */
        ModuleRouter.getInstance().onModulesCreate(defineModulesNeedManagedByModuleName());
    }

    @Override
    public void onTerminate() {
        super.onTerminate();
        /*
         * 组件化框架调用组件生命周期，非组件化无用
         */
        ModuleRouter.getInstance().onModulesTerminate(defineModulesNeedManagedByModuleName());
        unregisterActivityLifecycleCallbacks(this);
    }

    @Override
    public void onLowMemory() {
        super.onLowMemory();
        /*
         * 组件化框架调用组件生命周期，非组件化无用
         */
        ModuleRouter.getInstance().onModulesLowMemory(defineModulesNeedManagedByModuleName());
    }

    @Override
    public void onTrimMemory(int level) {
        super.onTrimMemory(level);
        /*
         * 组件化框架调用组件生命周期，非组件化无用
         */
        ModuleRouter.getInstance().onModulesTrimMemory(defineModulesNeedManagedByModuleName(), level);
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        /*
         * 组件化框架调用组件生命周期，非组件化无用
         */
        ModuleRouter.getInstance().onModulesConfigurationChanged(defineModulesNeedManagedByModuleName(), newConfig);
    }

    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(base);
        MultiDex.install(this);
    }

    @Override
    public void initModules() {
        ModuleRouter.getInstance().loadModules(this);
    }

    @Override
    public void initSharedPreference(String sharedName) {
        SharedUtils.initInstance(getApplicationContext(), sharedName);
    }

    /**
     * @return String
     */
    protected abstract String defineSharedPreferenceName();

    /**
     * define modules which need managed in Application lifecycle（组件化使用）
     *
     * @return String
     */
    protected abstract String[] defineModulesNeedManagedByModuleName();

    /**
     * get current activity
     *
     * @return Activity
     */
    public Activity getCurrentActivity() {
        return currentActivityList.size() == 0 ? null : currentActivityList.get(0).get();
    }

    /**
     * kill all activity
     */
    public void killAllActivity() {
        for (WeakReference<Activity> activity : activityList) {
            if (null != activity && null != activity.get()) {
                activity.get().finish();
            }
        }
    }

    /**
     * kill all activities Except!!!
     *
     * @param activityClass Except activity class
     */
    @SuppressWarnings("unchecked")
    public void killAllActivityExcept(Class<Activity> activityClass) {
        for (WeakReference<Activity> weakReference : activityList) {
            if (null != weakReference && null != weakReference.get() && !weakReference.get().getClass().equals(activityClass)) {
                weakReference.get().finish();
            }
        }
    }

    @Override
    public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
        activityList.add(new WeakReference<>(activity));
        if (activity instanceof BaseActivity) {
            ((BaseActivity) activity).registerPresenter();
        } else if (activity instanceof BaseAppCompatActivity) {
            ((BaseAppCompatActivity) activity).registerPresenter();
        } else if (activity instanceof BaseFragmentActivity) {
            ((BaseFragmentActivity) activity).registerPresenter();
        }
    }

    @Override
    public void onActivityStarted(Activity activity) {
        if (currentActivityList.size() == 0) {
            ModuleRouter.getInstance().enterForeground(defineModulesNeedManagedByModuleName());
        }
        currentActivityList.add(new WeakReference<>(activity));
    }

    @Override
    public void onActivityResumed(Activity activity) {
    }

    @Override
    public void onActivityPaused(Activity activity) {
    }

    @SuppressWarnings("unchecked")
    @Override
    public void onActivityStopped(Activity activity) {
        for (Iterator iterator = currentActivityList.iterator(); iterator.hasNext(); ) {
            WeakReference<Activity> weakReference = (WeakReference<Activity>) iterator.next();
            if (null != weakReference && null != weakReference.get() && weakReference.get() == activity) {
                iterator.remove();
            }
        }
        if (currentActivityList.size() == 0) {
            ModuleRouter.getInstance().enterBackground(defineModulesNeedManagedByModuleName());
        }
    }

    @SuppressWarnings("unchecked")
    @Override
    public void onActivityDestroyed(Activity activity) {
        if (activity instanceof BaseActivity) {
            ((BaseActivity) activity).unregisterPresenter();
        } else if (activity instanceof BaseAppCompatActivity) {
            ((BaseAppCompatActivity) activity).unregisterPresenter();
        } else if (activity instanceof BaseFragmentActivity) {
            ((BaseFragmentActivity) activity).unregisterPresenter();
        }

        for (Iterator iterator = activityList.iterator(); iterator.hasNext(); ) {
            WeakReference<Activity> weakReference = (WeakReference<Activity>) iterator.next();
            if (null != weakReference && null != weakReference.get() && weakReference.get() == activity) {
                iterator.remove();
            }
        }
    }

    @Override
    public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
    }
}
